use std::time::Duration;
use serde::Serialize;
use serde::Serializer;
use ffmpeg_next::decoder::{Video as VideoDecoder, Audio as AudioDecoder};
use std::thread::JoinHandle;

fn serialize_duration_as_millis<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_u64(duration.as_millis() as u64)
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum PlaybackStatus {
    Loading,
    Ready,
    Playing,
    Paused,
    Stopped,
    Error(String),
}

impl PlaybackStatus {
    pub fn as_ref(&self) -> PlaybackStatus {
        match self {
            PlaybackStatus::Loading => PlaybackStatus::Loading,
            PlaybackStatus::Ready => PlaybackStatus::Ready,
            PlaybackStatus::Playing => PlaybackStatus::Playing,
            PlaybackStatus::Paused => PlaybackStatus::Paused,
            PlaybackStatus::Stopped => PlaybackStatus::Stopped,
            PlaybackStatus::Error(e) => PlaybackStatus::Error(e.clone()),
        }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct VideoInfo {
    pub width: u32,
    pub height: u32,
    pub frame_rate: f64,
    #[serde(serialize_with = "crate::player::events::serialize_duration_as_millis")]
    pub duration: Duration,
    pub codec: String,
    pub bit_rate: Option<u64>,
}

#[derive(Debug, Clone, Serialize)]
pub struct AudioInfo {
    pub channels: u32,
    pub sample_rate: u32,
    #[serde(serialize_with = "crate::player::events::serialize_duration_as_millis")]
    pub duration: Duration,
    pub codec: String,
    pub bit_rate: Option<u64>,
}

pub struct PlayerState {
    pub status: PlaybackStatus,
    pub duration: Option<Duration>,
    pub position: Duration,
    pub video_info: Option<VideoInfo>,
    pub audio_info: Option<AudioInfo>,
    video_decoder: Option<VideoDecoder>,
    audio_decoder: Option<AudioDecoder>,
    pub volume: f32,
    pub muted: bool,
    pub speed: f32,
    pub video_enabled: bool,
    pub audio_enabled: bool,
    pub last_error: Option<String>,
    pub buffering_progress: f32,
    pub thread_handle: Option<JoinHandle<()>>,
}

impl std::fmt::Debug for PlayerState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("PlayerState")
            .field("status", &self.status)
            .field("duration", &self.duration)
            .field("position", &self.position)
            .field("video_info", &self.video_info)
            .field("audio_info", &self.audio_info)
            .field("video_decoder", &if self.video_decoder.is_some() { "Some(VideoDecoder)" } else { "None" })
            .field("audio_decoder", &if self.audio_decoder.is_some() { "Some(AudioDecoder)" } else { "None" })
            .field("volume", &self.volume)
            .field("muted", &self.muted)
            .field("speed", &self.speed)
            .field("video_enabled", &self.video_enabled)
            .field("audio_enabled", &self.audio_enabled)
            .field("last_error", &self.last_error)
            .field("buffering_progress", &self.buffering_progress)
            .finish()
    }
}

impl Default for PlayerState {
    fn default() -> Self {
        Self {
            status: PlaybackStatus::Loading,
            duration: None,
            position: Duration::from_secs(0),
            video_info: None,
            audio_info: None,
            video_decoder: None,
            audio_decoder: None,
            volume: 1.0,
            muted: false,
            speed: 1.0,
            video_enabled: true,
            audio_enabled: true,
            last_error: None,
            buffering_progress: 0.0,
            thread_handle: None,
        }
    }
}

impl Clone for PlayerState {
    fn clone(&self) -> Self {
        Self {
            status: self.status.clone(),
            duration: self.duration,
            position: self.position,
            video_info: self.video_info.clone(),
            audio_info: self.audio_info.clone(),
            video_decoder: None,  // 解码器不能被clone
            audio_decoder: None,  // 解码器不能被clone
            volume: self.volume,
            muted: self.muted,
            speed: self.speed,
            video_enabled: self.video_enabled,
            audio_enabled: self.audio_enabled,
            last_error: self.last_error.clone(),
            buffering_progress: self.buffering_progress,
            thread_handle: None,  // 线程句柄不能被clone
        }
    }
}

impl PlayerState {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn set_thread_handle(&mut self, handle: Option<JoinHandle<()>>) {
        // 如果已经有一个运行中的线程，先等待它结束
        if let Some(old_handle) = self.thread_handle.take() {
            log::info!("Waiting for previous playback thread to finish");
            if let Err(e) = old_handle.join() {
                log::error!("Error joining previous playback thread: {:?}", e);
            }
        }
        self.thread_handle = handle;
        log::info!("New playback thread handle set");
    }

    pub fn is_playing(&self) -> bool {
        matches!(self.status, PlaybackStatus::Playing)
    }

    pub fn set_status(&mut self, status: PlaybackStatus) {
        log::debug!("Setting playback status to {:?}", status);
        self.status = status;
    }

    pub fn set_duration(&mut self, duration: Duration) {
        log::debug!("Setting duration to {:?}", duration);
        self.duration = Some(duration);
    }

    pub fn set_position(&mut self, position: Duration) {
        self.position = position;
    }

    pub fn set_video_info(&mut self, info: VideoInfo) {
        log::debug!("Setting video info: {:?}", info);
        self.video_info = Some(info);
    }

    pub fn set_audio_info(&mut self, info: AudioInfo) {
        log::debug!("Setting audio info: {:?}", info);
        self.audio_info = Some(info);
    }

    pub fn set_video_decoder(&mut self, decoder: VideoDecoder) {
        self.video_decoder = Some(decoder);
    }

    pub fn set_audio_decoder(&mut self, decoder: AudioDecoder) {
        self.audio_decoder = Some(decoder);
    }

    pub fn set_volume(&mut self, volume: f32) {
        self.volume = volume.max(0.0).min(1.0);
    }

    pub fn volume(&self) -> f32 {
        self.volume
    }

    pub fn set_muted(&mut self, muted: bool) {
        self.muted = muted;
    }

    pub fn set_speed(&mut self, speed: f32) {
        self.speed = speed.max(0.0);
    }

    pub fn set_video_enabled(&mut self, enabled: bool) {
        self.video_enabled = enabled;
    }

    pub fn set_audio_enabled(&mut self, enabled: bool) {
        self.audio_enabled = enabled;
    }

    pub fn set_error(&mut self, error: Option<String>) {
        self.last_error = error;
    }

    pub fn set_buffering_progress(&mut self, progress: f32) {
        self.buffering_progress = progress.max(0.0).min(1.0);
    }

    pub fn get_effective_volume(&self) -> f32 {
        if self.muted {
            0.0
        } else {
            self.volume
        }
    }

    pub fn take_thread_handle(&mut self) -> Option<JoinHandle<()>> {
        self.thread_handle.take()
    }

    pub fn is_paused(&self) -> bool {
        matches!(self.status, PlaybackStatus::Paused)
    }

    pub fn is_stopped(&self) -> bool {
        matches!(self.status, PlaybackStatus::Stopped)
    }

    pub fn has_error(&self) -> bool {
        matches!(self.status, PlaybackStatus::Error(_))
    }

    pub fn get_error(&self) -> Option<String> {
        match &self.status {
            PlaybackStatus::Error(msg) => Some(msg.clone()),
            _ => None,
        }
    }
}
